home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / windc86.lqr / WINDOW.C < prev    next >
Text File  |  1985-06-03  |  8KB  |  296 lines

  1. /*    module:        window.c
  2.  *    programmer:    Ray L. McVay
  3.  *    started:    1 Aug 84
  4.  *    version:    1.2, 23 Aug 84
  5.  *
  6.  *    A simple window package based on the article and programs
  7.  *    by Edward Mitchell in the Jan 84 Dr. Dobb's Journal.  This
  8.  *    implementation uses dynamically allocated buffers for the
  9.  *    window control blocks and screen save buffers.
  10.  *
  11.  *    An assembly language support library called VLIB is used to
  12.  *    interface the DeSmet C compiler with the IBM ROM BIOS video
  13.  *    routines.  VLIB will undoubtedly have to be rewritten if the
  14.  *    window package is to be used with other compilers.
  15.  *
  16.  *    History -
  17.  *
  18.  *    1.1    -    Added style member to wcb structure, clr_window() and
  19.  *            use of wn->cx for horizontal scrolling in write_text().
  20.  *
  21.  *    1.2 -    Added oldx, oldy members to wcb structure and use them
  22.  *            in draw_window() and remove_window().
  23.  *
  24.  *  Dec 84 - vlib.asm rewriten to assemble using MASM creating vlib.obj
  25.  *           making it compatable with Computer Inovations C86 Compiler
  26.  *           by Mike Elkins (619) 722-4363. 
  27.  */
  28.  
  29.  
  30.  
  31. /************************************************************************
  32. * putch(), write a character and attribute to a specific XY location on *
  33. *           the screen. The attribute is the high byte of the character.    *
  34. ************************************************************************/
  35.  
  36. putch(x, y, c)
  37. int        x, y, c;
  38. {
  39.     gotoxy_(x, y, 0);
  40.     vputca_(c, 0, 1);
  41. }
  42.  
  43.  
  44. /************************************************************************
  45. * getch(), return the character and attribute at screen XY                *
  46. ************************************************************************/
  47.  
  48. getch(x, y)
  49. int        x, y;
  50. {
  51.     gotoxy_(x, y, 0);
  52.     return(vgetc_(0));
  53. }
  54.  
  55.  
  56. /************************************************************************
  57. * draw_row(), output a row of one character/attribute at XY                *
  58. ************************************************************************/
  59.  
  60. draw_row(x, y, count, c)
  61. int        x, y, count,c;
  62. {
  63.     gotoxy_(x, y, 0);
  64.     vputca_(c, 0, count);
  65. }
  66.  
  67.  
  68. /************************************************************************
  69. * draw_window(), open a window of given size with upper left corner at    *
  70. *                 XY. Allocates buffers for the window control block and *
  71. *                 screen save buffers. Copies overwritten screen to the    *
  72. *                 buffer. Draws the blank window. Returns the address of    *
  73. *                 the window control block or NULL if no buffer space.    *
  74. ************************************************************************/
  75.  
  76. WINDOWPTR draw_window(x, y, width, height, attrib)
  77. int        x, y, width, height, attrib;
  78. {
  79.     WINDOWPTR wn;
  80.     int        tx, ty,
  81.             xend, yend;
  82.     int        *tptr;
  83.     char    *calloc();
  84.  
  85.     if ((wn = (WINDOWPTR)calloc(1, sizeof(WINDOW))) == NULL)
  86.         return(NULL);
  87.     else if ((wn->scrnsave = (int *)calloc((width+2) * (height+2), sizeof(int))) == NULL)
  88.     {
  89.         free(wn);
  90.         return(NULL);
  91.     }
  92.     else
  93.     {
  94.         /* store parameters in window control block */
  95.  
  96.         wn->ulx = x;
  97.         wn->uly = y;
  98.         wn->xsize = width;
  99.         wn->ysize = height;
  100.         wn->cx = 1;
  101.         wn->cy = 1;
  102.         wn->style = attrib;
  103.         attrib <<= 8;    /* will make things below go quicker */
  104.         wn->oldx = getxy_(0) & 255;
  105.         wn->oldy = getxy_(0) >> 8;
  106.  
  107.         /* Copy existing text where the window will be placed */
  108.         /* to the scrnsave buffer. Obviously, a less portable */
  109.         /* routine could be much faster.                      */
  110.  
  111.         tptr = wn->scrnsave;
  112.         xend = x + width + 2;
  113.         yend = y + height + 2;
  114.  
  115.         for (ty = y; ty < yend; ty++)
  116.         {
  117.             for (tx = x; tx < xend; tx++)
  118.                 *tptr++ = getch(tx, ty);
  119.         }
  120.  
  121.         /* draw the window border and clear the text area */
  122.  
  123.         putch(x, y, 0xda + attrib);                    /* ul corner */
  124.         draw_row(x + 1, y, width, 0xc4 + attrib);    /* horiz bar */
  125.         putch(x + width + 1, y, 0xbf + attrib);        /* ur corner */
  126.  
  127.         yend = y + height;
  128.  
  129.         for (ty = y+1; ty <= yend; ty++)
  130.         {
  131.             putch(x, ty, 0xb3 + attrib);            /* draw the sides */
  132.             putch(x+width+1, ty, 0xb3 + attrib);
  133.         }
  134.  
  135.         putch(x, y + height + 1, 0xc0 + attrib);                /* ll corner */
  136.         draw_row(x + 1, y + height + 1, width, 0xc4 + attrib);    /* horiz bar */
  137.         putch(x + width + 1, y + height + 1, 0xd9 + attrib);    /* lr corner */
  138.  
  139.         clr_window(wn);
  140.  
  141.         return(wn);
  142.     }
  143. }
  144.  
  145.  
  146. /************************************************************************
  147. * remove_window(), erase the window at the window control block.        *
  148. *                   Must be the "top" window if overlapping windows are  *
  149. *                   used. "Tiled" windows could be removed randomly.        *
  150. ************************************************************************/
  151.  
  152. remove_window(wn)
  153. WINDOWPTR wn;
  154. {
  155.     int        tx, ty,
  156.             xend, yend;
  157.     int        *tptr;
  158.  
  159.     /* just repaint the saved text at the appropriate location */
  160.  
  161.     tptr = wn->scrnsave;
  162.     xend = wn->ulx + wn->xsize + 2;
  163.     yend = wn->uly + wn->ysize + 2;
  164.  
  165.     for (ty = wn->uly; ty < yend; ty++)
  166.     {
  167.         for (tx = wn->ulx; tx < xend; tx++)
  168.             putch(tx, ty, *tptr++);
  169.     }
  170.  
  171.     /* put cursor back where it was before this rude interruption */
  172.  
  173.     gotoxy_(wn->oldx, wn->oldy, 0);
  174.  
  175.     /* then release the dynamic storage used */
  176.  
  177.     free(wn->scrnsave);
  178.     free(wn);
  179. }
  180.  
  181.  
  182. /************************************************************************
  183. * write_text(), print a string inside a window using cx, cy in WCB        *
  184. ************************************************************************/
  185.  
  186. write_text(wn, string)
  187. WINDOWPTR wn;
  188. char    *string;
  189. {
  190.     int        tx, ty, xend;
  191.  
  192.     /* first check to see if we're at the bottom of the window        */
  193.     /* if we are then scroll the contents of the window up            */
  194.  
  195.     if (wn->cy > wn->ysize)
  196.     {
  197.         delete_row(wn, 1);
  198.         --wn->cy;
  199.     }
  200.  
  201.     /* Print as much of the string as will fit in the window.        *
  202.      * cx is used for relative left margin. If cx is negative then    *
  203.      * the first cx characters will be removed from the string to    *
  204.      * allow horizontal scrolling in the window.                    *
  205.      * NOTE: This obviously simple-minded technique is usable for    *
  206.      *          displaying predetermined messages but a more general    *
  207.      *         console output intercept should be used for Star-like    *
  208.      *         environments.                                            */
  209.  
  210.     if (wn->cx > 0)
  211.         tx = wn->ulx + wn->cx;
  212.     else
  213.     {
  214.         if (-wn->cx < strlen(string))
  215.             string -= wn->cx;
  216.         else
  217.             *string = '\0';
  218.         tx = wn->ulx + 1;
  219.     }
  220.     xend = wn->ulx + wn->xsize + 1;
  221.     ty = wn->uly + wn->cy;
  222.     while ((tx < xend) && *string)
  223.     {
  224.         gotoxy_(tx++, ty, 0);
  225.         vputc_(*string++, 0, 1);
  226.     }
  227.     ++wn->cy;        /* move the internal cursor to the next line */
  228. }
  229.  
  230.  
  231. /************************************************************************
  232. * insert_row(), insert a row of blanks by scrolling the lower portion    *
  233. *                of a window down                                        *
  234. ************************************************************************/
  235.  
  236. insert_row(wn, row)
  237. WINDOWPTR wn;
  238. int        row;
  239. {
  240.     int        scrlwn[4];
  241.  
  242.     /* calculate corners of the scrolling window */
  243.  
  244.     scrlwn[0] = wn->ulx + 1;            /* ulx */
  245.     scrlwn[1] = wn->uly + row;            /* uly */
  246.     scrlwn[2] = wn->ulx + wn->xsize;    /* lrx */
  247.     scrlwn[3] = wn->uly + wn->ysize;    /* lry */
  248.  
  249.     scrldn_(scrlwn, 1, wn->style);
  250. }
  251.  
  252.  
  253. /************************************************************************
  254. * delete_row(), delete a row by scrolling the lower portion of a window *
  255. *                up and inserting a row of blanks at the bottom row        *
  256. ************************************************************************/
  257.  
  258. delete_row(wn, row)
  259. WINDOWPTR wn;
  260. int        row;
  261. {
  262.     int        scrlwn[4];
  263.  
  264.     /* calculate corners of the scrolling window */
  265.  
  266.     scrlwn[0] = wn->ulx + 1;            /* ulx */
  267.     scrlwn[1] = wn->uly + row;            /* uly */
  268.     scrlwn[2] = wn->ulx + wn->xsize;    /* lrx */
  269.     scrlwn[3] = wn->uly + wn->ysize;    /* lry */
  270.  
  271.     scrlup_(scrlwn, 1, wn->style);
  272. }
  273.  
  274.  
  275. /************************************************************************
  276. * clr_window(), clear the "active" part of a window    and "home" internal    *
  277. *                text cursor                                                *
  278. ************************************************************************/
  279.  
  280. clr_window(wn)
  281. WINDOWPTR wn;
  282. {
  283.     int        scrlwn[4];
  284.  
  285.     /* calculate corners of the scrolling window */
  286.  
  287.     scrlwn[0] = wn->ulx + 1;            /* ulx */
  288.     scrlwn[1] = wn->uly + 1;            /* uly */
  289.     scrlwn[2] = wn->ulx + wn->xsize;    /* lrx */
  290.     scrlwn[3] = wn->uly + wn->ysize;    /* lry */
  291.  
  292.     scrlup_(scrlwn, 0, wn->style);
  293.     wn->cx = 1;
  294.     wn->cy = 1;
  295. }
  296.